#include "stdafx.h"
#include "KSprFile.h"

void SprFrame2Bitmap(
					 KSprFrameHeader *pFrameHeader,
					 const COLOR32* pal32,
					 int colors,
					 int ColorKey,
					 const BYTE* pixels,
					 const char* bmpname)
{
	BITMAPFILEHEADER bmpfh;
	BITMAPINFOHEADER bmpih;

	bmpfh.bfType = 0x4d42;
	bmpfh.bfReserved1 = 0;
	bmpfh.bfReserved2 = 0;
	bmpfh.bfOffBits = sizeof(bmpfh) + sizeof(bmpih) + sizeof(COLOR32) * colors;

	bmpfh.bfSize = pFrameHeader->width * pFrameHeader->height * 8 + 
		sizeof(bmpfh) + sizeof(bmpih) + sizeof(COLOR32) * colors;	

	memset(&bmpih, 0, sizeof(bmpih));
	bmpih.biClrUsed = colors;
	bmpih.biSize = sizeof(bmpih);
	bmpih.biWidth = pFrameHeader->width;
	bmpih.biHeight = pFrameHeader->height;
	bmpih.biPlanes = 1;
	bmpih.biBitCount = 8;
	bmpih.biCompression = BI_RGB;
	bmpih.biSizeImage = pFrameHeader->width * pFrameHeader->height;

	krt::FileStream fs;

	if (!fs.open(bmpname, krt::FileStream::fmCreate))
		return;

	fs.write(&bmpfh, sizeof(bmpfh));
	fs.write(&bmpih, sizeof(bmpih));
	fs.write(pal32, sizeof(COLOR32) * colors);

	int BytesPerLine = (pFrameHeader->width + 3) / 4 * 4;

	BYTE* line = (BYTE*)malloc(BytesPerLine);

	memset(line, 0, BytesPerLine);

	for(int y = 0; y < pFrameHeader->height; ++y)
	{
		int x = 0;

		while (x < pFrameHeader->width)
		{
			BYTE cnt = *(pixels++);
			BYTE alpha = *(pixels++);

			if (0 == alpha)
				memset(line + x, ColorKey, cnt);
			else
			{
				memcpy(line + x, pixels, cnt);
				pixels += cnt;

			}

			x += cnt;
		}

		fs.seek(bmpfh.bfOffBits + (pFrameHeader->height - 1 - y) * BytesPerLine, krt::stream::soFromBeginning);
		fs.write(line, BytesPerLine);
	}
}

void Spr2Bitmaps(
				 krt::stream& spr, 
				 const char* dstdir)
{
	KSprFileHeader FileHeader;

	if (sizeof(FileHeader) != spr.read(&FileHeader, sizeof(FileHeader)) 
		|| SPR_SIGNATURE != FileHeader.signature)
	{
		printf("invalid file format\n");
		return;
	}

	printf(
		"file header:\n\twidth=%d\n\theight=%d\n\tcolors=%d\n\tframes=%d\n\tdirections=%d"\
		"\n\tinterval=%d\n\tcenter_x=%d\n\tcenter_y=%d\n",
		FileHeader.width,
		FileHeader.height,
		FileHeader.colors,
		FileHeader.frames,
		FileHeader.directions,
		FileHeader.interval,
		FileHeader.center_x,
		FileHeader.center_y);

	krt::AutoBuffer PalData;

	PalData.alloc(sizeof(COLOR24) * FileHeader.colors);

	// read palette table
	COLOR24* pal24 = (COLOR24*)PalData.GetBuffer();

	if (sizeof(COLOR24) * FileHeader.colors != 
		spr.read(pal24, PalData.GetLength()))
	{
		return;
	}

	COLOR32 pal32[256];

	int ColorKey = 0;

	BOOL flag = false;

	for(int i = 0; i < FileHeader.colors; ++i)
	{
		pal32[i].alpha = 0;
		pal32[i].red = pal24[i].red;
		pal32[i].green = pal24[i].green;
		pal32[i].blue = pal24[i].blue;

		if (0 == *((long*)&pal32[i]))
		{
			if (flag)
			{
				ColorKey = i;
				*((long*)&pal32[i]) = 0xffff00ff;
			}
			else
				flag = true;
		}
	}


	/*for(int i = 0; i < FileHeader.colors; ++i)
	{
	printf("pal[%d]: RGB(%d,%d,%d)\n", i, pal24[i].red, pal24[i].green, pal24[i].blue);
	}*/

	krt::AutoBuffer IndexData;

	IndexData.alloc(sizeof(KSprFrameEntry) * FileHeader.frames);

	KSprFrameEntry* frame_entries = (KSprFrameEntry*)IndexData.GetBuffer();

	if (IndexData.GetLength() !=  spr.read(frame_entries, IndexData.GetLength()))
	{
		return;
	}	

	krt::StaticArray<char, MAX_PATH> sprdir(dstdir);  
	size_t bm = sprdir.GetLength();

	for(UINT16 i = 0; i < FileHeader.frames; ++i)
	{
		KSprFrameHeader* pFrameHeader = 
			(KSprFrameHeader*)malloc(frame_entries[i].length);

		if (frame_entries[i].length != 
			spr.read(pFrameHeader, frame_entries[i].length))
		{
			free(pFrameHeader);
			return;
		}

		printf("frame %d\n\twidth=%d\n\theight=%d\n\toffsetx=%d\n\toffsety=%d\n",
			i,
			pFrameHeader->width,
			pFrameHeader->height,
			pFrameHeader->offsetx,
			pFrameHeader->offsety);

		char bmpname[MAX_PATH];

		sprdir.SetLength(bm);
		sprdir.AppendPath(bmpname, sprintf(bmpname, "%d.bmp", i));

		SprFrame2Bitmap(
			pFrameHeader, 
			pal32, 
			FileHeader.colors,
			ColorKey,
			pFrameHeader->pixels,
			sprdir.GetBuffer());

		free(pFrameHeader);
	}
}

void Spr2Bitmaps(const char* sprname)
{
	krt::FileStream fs;
	
	if (!fs.open(sprname, krt::FileStream::fmOpenRead))
	{
		printf("file not found\n");
		return;
	}

	char sprdir[MAX_PATH];
	char file_name[MAX_PATH];

	krt::ExtractFilePath(sprname, (size_t)-1, sprdir);
	krt::ExtractFileName(sprname, (size_t)-1, file_name);
	krt::DeleteFileExt(file_name, (size_t)-1);
	strcat(sprdir, file_name);

	_mkdir(sprdir);

	Spr2Bitmaps(fs, sprdir);
}


